﻿//
// Syrius Robotics Ltd. Co. CONFIDENTIAL
//
// Unpublished Copyright (c) 2018 - 2021 [Syrius Robotics Ltd. Co.],
// All Rights Reserved.
//
//    Authors: Li Rongye <lirongye@syriusrobotics.com>
//


#ifndef SIMPLELOG_H
#define SIMPLELOG_H


#ifdef USE_GLOG
#   include <glog/logging.h>
#   define LOCATION_INFO __FUNCTION__ << "() "
#else
#   include <iostream>
#   define LOG(level) std::cout
#ifndef __FILENAME__
#   define __FILENAME__ __FILE__
#endif
#   define LOCATION_INFO  "[" << __FUNCTION__ << "() " << __FILENAME__ << ":" << __LINE__ << "] "
#endif

#include "std_def.h"
#include "traverse__VA_ARGS__mocro.h"

#define CAST_2_INT(uint8value) (static_cast<int>(uint8value))
#define NONE(format, ...) ((void)0)

#define QPRINT_ONE_VAR(var, type) #var "=" << var
#define QVAR_CONNECT_INFO << ", "
#define QFOR_EACH_VAR(v1, ...) FOR_EACH(QPRINT_ONE_VAR, "he he", QVAR_CONNECT_INFO, v1, ##__VA_ARGS__)

#define DEBUG_PRINT  LOG(INFO) << LOCATION_INFO
/**
 * @brief QPRINT_VAR Print out the values of several variables and variable
 * names
 * @param v1, ...: Several values
 */
#define QPRINT_VAR(v1, ...) LOG(INFO) << LOCATION_INFO << QFOR_EACH_VAR(v1, ##__VA_ARGS__) << std::endl
#define QPRINT_VAR_E(v1, ...) LOG(ERROR) << LOCATION_INFO << "Here error!! " << QFOR_EACH_VAR(v1, ##__VA_ARGS__) << std::endl

#define QPRINT_VAR2(str, v1, ...) LOG(INFO) << LOCATION_INFO << str << " " << QFOR_EACH_VAR(v1, ##__VA_ARGS__) << std::endl
#define QPRINT_VAR2_E(str, v1, ...) LOG(ERROR) << LOCATION_INFO << "Here error!! " << str << " " << QFOR_EACH_VAR(v1, ##__VA_ARGS__) << std::endl

#define HERE LOG(INFO) << LOCATION_INFO << "Here" << std::endl
#define HERE_ERROR LOG(ERROR) << LOCATION_INFO << "Here error!!" << std::endl
#define QPRINT_ERROR(errorCode) LOG(ERROR) << LOCATION_INFO << "Here error!! errorCode: " << firmware_updater::ErrorText(errorCode) << "(" << (errorCode) << ")" << std::endl

#ifndef BUILD_TIME
#    define BUILD_TIME __DATE__ " " __TIME__
#endif

#if __cplusplus >= 201402L
#    undef __FUNCTION__
#    define __FUNCTION__ _CutParenthesesNTail(__PRETTY_FUNCTION__)
namespace hal
{
static char __private_simplelog_buf[255];
constexpr const char * _CutParenthesesNTail(const char * name)
{
    strncpy(__private_simplelog_buf, name, sizeof(__private_simplelog_buf));
    char * p     = __private_simplelog_buf;
    char * begin = p;
    char * end   = p;
    while (*p != '\0')
    {
        ++p;
        if (' ' == *p) { begin = p + 1; }
        if ('(' == *p)
        {
            end = p;
            break;
        }
    }

    *end = '\0'; // gaisini
    return begin;
}

} // namespace hal
#endif
#define PRINT_DATA_HEX(p, size) hal::printDataHex((const unsigned char *)(p), (int)(size), __FUNCTION__, __FILE__, __LINE__)

#include <assert.h>
namespace hal
{
static constexpr int LINE_BYTES_COUNT_         = 25;
static constexpr const char * SAVE_HEX_FORMAT_ = "%02X ";
inline void printDataHex(const unsigned char * pData, int size, const char * pFuncName = NULL, const char * pFileName = NULL, int line = -1)
{
    assert(pData != NULL);
    assert(size > 0);
    printf("[%s:%d %s()] print %d Bytes data:\n", pFileName, line, pFuncName, size);

    for (int i = 0; i < size; ++i)
    {
        printf(SAVE_HEX_FORMAT_, pData[i]);
        if (0 == (i + 1) % LINE_BYTES_COUNT_) { printf("\n"); }
    }

    printf("\n[%s:%d %s()] print data OVER\n\n", pFileName, line, pFuncName);
}

} // namespace hal

#endif // SIMPLECOMMACRO_H
